package pub.cleangao.codegen.literal;


import com.jfinal.template.Engine;
import pub.cleangao.codegen.GenConfigHolder;
import pub.cleangao.codegen.util.EnjoyEngine;
import pub.cleangao.common.util.Resources;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 规则:
 * 1. 全部的文件都位于根包下(配置文件中有配置)
 * 2. 在index.txt中使用`package:文件名`的方式,
 * package为在根包下建立的新包, 可以为空; 文件名必须与templates/commons/下文件名一致
 * 3. 一条记录占用一行
 */
public class CommonsBuilder {

    private static final String commonsFolder = "templates/commons/";
    private static final String commonsServiceIndex = commonsFolder + "service_package_file.index";
    private static final String commonsStubIndex = commonsFolder + "api_package_file.index";

    private static final Engine engine = Engine.create("commons-assembler");


    /**
     * 构建通用文件
     */
    public static void buildServiceCommons(GenConfigHolder config) {
        List<String> indexServiceAll = loadCommonIndexes(commonsServiceIndex);
        for (String line : indexServiceAll) {
            LiteralResult result = getLinedResult(line, config, false);
            LiteralProducer.outputToDisk(result);
        }
    }

    /**
     * 构建stub通用文件
     */
    public static void buildStubCommons(GenConfigHolder config) {
        List<String> indexStubAll = loadCommonIndexes(commonsStubIndex);
        for (String line : indexStubAll) {
            LiteralResult result = getLinedResult(line, config, true);
            if (result == null) {
                continue;
            }
            LiteralProducer.outputToDisk(result);
        }
    }


    private static List<String> loadCommonIndexes(String filePath) {
        List<String> rst = new ArrayList<>();
        try {
            InputStream inputStream = Resources.getResourceAsStream(filePath);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = null;
            while ((line = bufferedReader.readLine()) != null) {
                line = line.trim();
                if (line == null || line.isEmpty()) {
                    continue;
                }
                if (line.startsWith("#")) {
                    // 注释行
                    continue;
                }
                if (line.startsWith(";")) {
                    // 注释行
                    continue;
                }
                if (line.startsWith("//")) {
                    // 注释行
                    continue;
                }
                rst.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return rst;
    }

    private static LiteralResult getLinedResult(String line, GenConfigHolder config, boolean isApiStub) {
        String basePackage = config.getBasePackage();
        String rootPath = config.getRootPath();
        if (!config.isSinglePot()) {
            String serviceModule = null;
            if (!isApiStub) {
                serviceModule = config.getServiceModule();
                if (serviceModule == null || serviceModule.isBlank()) {
                    serviceModule = ProjectStruct.serviceProviderModule;
                }
            } else {
                serviceModule = config.getStubModule();
                if (serviceModule == null || serviceModule.isBlank()) {
                    serviceModule = ProjectStruct.serviceStubModule;
                }
            }
            rootPath = rootPath + "/" + serviceModule;
        }
        rootPath = rootPath + "/" + ProjectStruct.javaCodePath;
        LiteralResult result = new LiteralResult();
        String[] packageFile = line.split(":");
        String packageI = packageFile[0];
        String currentPackage = null;
        if (packageI == null || packageI.trim().equals("")) {
            currentPackage = basePackage;
        } else {
            if (packageI.contains(basePackage)) {
                currentPackage = packageI;
            } else {
                currentPackage = basePackage + "." + packageI.trim();
            }
        }
        String fileName = packageFile[1].trim();
        if (fileName == null || fileName.isEmpty()) {
            return null;
        }
        result.setFileName(fileName);
        String fileResourcePath = commonsFolder + fileName;
        Map<String, Object> context = new HashMap<>();
        result.setPackageName(currentPackage);
        result.setFolderPath(rootPath + currentPackage.replace(".", "/"));
        context.put("package", currentPackage);
        result.setContent(EnjoyEngine.assemble(fileResourcePath, context));
        result.setClassName(fileName.substring(0, fileName.lastIndexOf(".")));
        result.setFilePath(result.getFolderPath() + "/" + result.getFileName());
        return result;
    }

}
